<template>
  <a-modal :width="'1000px'" :visible="visible" :destroyOnClose="true" :maskClosable="false" :keyboard="false"
    wrapClassName="hv-dark-dialog hv-http-request-dialog" :title="title" @cancel="handleCancel">
    <template #footer>
      <a-button @click="handleCancel">取消</a-button>
      <a-button type="primary" @click="handleOk" v-if="!readonly"> 确定</a-button>
    </template>
    <div class="hv-http-request-dialog-body">
      <a-row>
        <a-col :span="8">
          <a-form-item label="请求方法" :labelCol="labelCol">
            <a-select v-model:value="httpRequestConfig.method" placeholder="请选择方法..."
              dropdownClassName="hv-dark-select-dropdown">
              <a-select-option :value="option.value" v-for="(option, itemIndex) in httpRequestMethodListConst"
                :key="option.value + itemIndex">{{ option.label }}</a-select-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item label="自动刷新" :labelCol="labelCol">
            <a-switch checked-children="开启自动刷新" un-checked-children="关闭自动刷新"
              v-model:checked="httpRequestConfig.autoReload" />
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item label="刷新频率" :labelCol="labelCol">
            <a-input-number v-model:value="httpRequestConfig.reloadTime" :min="1000" :step="500" :max="240000" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row>
        <a-col :span="24">
          <a-form-item label="请求参数" :labelCol="labelCol">
            <hv-param-list-input v-model:value="httpRequestConfig.params" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-row>
        <a-col :span="24">
          <a-form-item label="请求地址" :labelCol="labelCol">
            <a-input v-model:value="httpRequestConfig.url" />
          </a-form-item>
        </a-col>
      </a-row>
      <codemirror v-model:modelValue="httpRequestConfig.resultHandle" :placeholder="placeholder"
        :style="{ height: height }" :autofocus="true" :indent-with-tab="true" :tab-size="tabSize" :lint="true"
        :disabled="readonly" :extensions="extensions" @ready="handleReady" @update="handleStateUpdate"
        ref="codemirrorRef" />
      <a-row>
        <a-col :span="24">
          <a-form-item label="结果处理" :labelCol="labelCol">
            <div class="hv-http-request-dialog-codemirror">

            </div>
            <div class="hv-http-request-dialog-footer">
              <div class="hv-http-request-dialog-footer-infos">
                <div>空格: {{ tabSize }}</div>
                <div>长度: {{ state.length }}</div>
                <div>行数: {{ state.lines }}</div>
                <div>光标: {{ state.cursor }}</div>
                <div>行中: {{ state.selected }}</div>
              </div>
            </div>
          </a-form-item>
        </a-col>
      </a-row>

      <a-row>
        <a-col :span="24">
          <a-form-item label="请求结果" :labelCol="labelCol">
            <div class="hv-http-request-dialog-codemirror">
              <codemirror :modelValue="httpRequestConfig.resultHandle" :placeholder="placeholder"
                :style="{ height: height }" :autofocus="true" :indent-with-tab="true" :tab-size="tabSize" :lint="true"
                :disabled="readonly" :extensions="extensions" @update:modelValue="updateValue" @ready="handleReady"
                @update="handleStateUpdate" ref="codemirrorRef" />
            </div>
            <div class="hv-http-request-dialog-footer">
              <div class="hv-http-request-dialog-footer-infos">
                <div>空格: {{ tabSize }}</div>
                <div>长度: {{ state.length }}</div>
                <div>行数: {{ state.lines }}</div>
                <div>光标: {{ state.cursor }}</div>
                <div>行中: {{ state.selected }}</div>
              </div>
            </div>
          </a-form-item>
        </a-col>
      </a-row>

      <a-row>
        <a-col :span="24">
          <a-button type="primary" size="small" @click="testHttpRequest">测试请求</a-button>
        </a-col>
      </a-row>
    </div>

  </a-modal>
</template>

<script setup lang="ts">
import { Codemirror } from "vue-codemirror";
import { javascript } from "@codemirror/lang-javascript";
import { oneDark } from "@codemirror/theme-one-dark";
import { type PropType, reactive, ref, shallowRef, watch, nextTick } from "vue";
import type { EditorView, ViewUpdate } from "@codemirror/view";
import { notification } from "ant-design-vue";
import type DataSourceGroupType from "@/visual/commons/types/data-source-group-type";
import { httpRequestMethodConst, httpRequestMethodListConst } from '@/visual/commons/consts/dashboard-const';
import type DataSourceGroupHttpReqConfigType from "@/visual/commons/types/data-source-group-http-req-config-type";
import { cloneDeep } from 'lodash';
import HvParamListInput from './ParamListInput.vue';


const props = defineProps({
  readonly: {
    type: Boolean,
    default: false,
  },
  visible: {
    type: Boolean,
    default: false,
  },
  dataSource: {
    type: Object as PropType<DataSourceGroupType>,
    default: () => {
      return {
        type: "",
        jsonConfig: {
          data: "{}",
        },
        httpRequestConfig: {
          method: httpRequestMethodConst.get,
          autoReload: false,
          reloadTime: 60000,
          url: "",
          params: {},
          resultHandle: '(data) => data',
        },
      };
    },
  },
  tabSize: {
    type: Number,
    default: 2,
  },
  title: {
    type: String,
    default: "编辑数据",
  },
  placeholder: {
    type: String,
    default: "返回结果...",
  },
  height: {
    type: String,
    default: "200px",
  },
});

const emit = defineEmits(["update:visible", "update:dataSource"]);

const labelCol = { style: { width: '85px' } };

const httpRequestConfig = ref<DataSourceGroupHttpReqConfigType>({
  method: httpRequestMethodConst.get,
  autoReload: false,
  reloadTime: 60000,
  url: '',
  params: {},
  resultHandle: '(data) => data',
})

const editorView = shallowRef<EditorView>();
const state = reactive({
  lines: null as null | number,
  cursor: null as null | number,
  selected: null as null | number,
  length: null as null | number,
});


const extensions = [javascript(), oneDark];

const handleReady = ({ view }: any) => {
  editorView.value = view;
};

const handleStateUpdate = (viewUpdate: ViewUpdate) => {
  const ranges = viewUpdate.state.selection.ranges;
  state.selected = ranges.reduce((plus, range) => plus + range.to - range.from, 0);
  state.cursor = ranges[0].anchor;
  state.length = viewUpdate.state.doc.length;
  state.lines = viewUpdate.state.doc.lines;
};

const validateJson = (val: string) => {
  try {
    return JSON.parse(val);
  } catch (e: any) {
    console.error(e.message);
    return null;
  }
};

const formatting = (jsonString) => {
  const json = validateJson(jsonString);
  if (null !== json) {
    return JSON.stringify(json, null, "\t");
  } else {
    return "";
  }
};

const formattingResultHandle = () => {
  console.info(httpRequestConfig.value.resultHandle)
  return httpRequestConfig.value.resultHandle;
}

const updateValue = (val) => {
  httpRequestConfig.value.resultHandle = val;
};

/**
 * 取消
 */
const handleCancel = () => {
  emit("update:visible", false);
};

const testHttpRequest = () => {
  console.info(httpRequestConfig.value)
}

const handleOk = () => {

};

watch(
  () => props.dataSource.httpRequestConfig,
  () => {
    console.info(props.dataSource.httpRequestConfig)
    httpRequestConfig.value = cloneDeep(props.dataSource.httpRequestConfig);
  },
  { immediate: true, deep: true }
);

</script>

<style lang="less" scoped>
@import "./HttpRequestDialog.less";
</style>
